﻿using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Xml;

namespace QDT.Payment.AllInPay.Api
{
    /// <summary>
    /// 报文基类
    /// </summary>
    public class CustomPackage : BasePackage
    {
        /// <summary>报文XML文档对象</summary>
        protected XmlDocument m_package;
        /// <summary>报文XML文档信息头对象</summary>
        protected XmlElement m_elInfo;
        /// <summary>报文XML文档信息体对象</summary>
        protected XmlElement m_elBody;
        /// <summary>单笔实时返回报文XML文档信息体对象</summary>
        protected XmlElement m_elTransRet;
        /// <summary>
        /// 报文XML文档对象
        /// </summary>
        internal CustomPackage()
        {
        }

        /// <summary>
        /// 输出包含签名信息的报文XML文档文本
        /// </summary>
        /// <returns>报文XML文档文本</returns>
        internal virtual string ToXML()
        {
            string xml;
            if (m_package != null)
            {
                xml = m_package.OuterXml;
                if (x509 != null)
                {
                    string signeNodeStr = "<SIGNED_MSG></SIGNED_MSG>";
                    int pos = xml.IndexOf(signeNodeStr);
                    if (pos == -1)
                    {
                        signeNodeStr = "<SIGNED_MSG />";
                        pos = xml.IndexOf(signeNodeStr);
                    }
                    if (pos == -1) return xml;
                    string signeText = xml.Replace(signeNodeStr, "");

                    SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
                    byte[] msg = sha1.ComputeHash(Encoding.GetEncoding(InternalConstants.Encode).GetBytes(signeText));

                    RSAPKCS1SignatureFormatter signe = new RSAPKCS1SignatureFormatter();

                    signe.SetKey(x509.PrivateKey);
                    signe.SetHashAlgorithm("SHA1");
                    signeText = ToHex(signe.CreateSignature(msg));

                    xml = xml.Substring(0, pos) + "<SIGNED_MSG>" + signeText + "</SIGNED_MSG>" + xml.Substring(pos + signeNodeStr.Length);
                }
            }
            else
                xml = string.Empty;
            return xml;
        }

        private static char[] hexChars = "0123456789abcdef".ToCharArray();

        private string ToHex(byte[] ba)
        {
            if (ba == null) return "";
            char[]
                buf = new char[ba.Length * 2];

            int p = 0;
            foreach (byte b in ba)
            {
                buf[p++] = hexChars[b >> 4];
                buf[p++] = hexChars[b & 0x0f];
            }
            return new string(buf);
        }

        /// <summary>
        /// 输出报文XML文档文本的GBK编码字节数组
        /// </summary>
        /// <returns>报文XML文档文本的GBK编码字节数组</returns>
        internal byte[] ToGBKBytes()
        {
            string xmlText = ToXML();
            return Encoding.GetEncoding(InternalConstants.Encode).GetBytes(xmlText);
        }

        private X509Certificate2 x509 = null;

        internal X509Certificate2 Certificate
        {
            get { return x509; }
            set { x509 = value; }
        }
    }
}
